package model;

import java.util.ArrayList;
import java.util.List;

/**
 * Classe representant le gestionnaire des threads
 * @author Lefevre, Thoue
 */
public class Manager {

    private Serveur serveur;
    private List<User> conversations;
    private EmetteurUDP emetteur;
    private RecepteurUDP recepteur;
    private Model model;
    /**
     * Constructeur
     * @param model lien vers le model de l'application
     */
    public Manager(Model model) {
        this.model = model;
        conversations = new ArrayList<User>();
        serveur = new Serveur(this);
        recepteur = new RecepteurUDP(this);
        emetteur = new EmetteurUDP(this);
    }
    /**
     * Demarre le serveur d'ecoute tcp et l'emetteur de son pour tester le volume du son
     */
    public void ecoute() {
        serveur.start();
        emetteur.start();
    }
    /**
     * Appel un utilisateur
     * @param ip adresse ip d'ecoute de l'utilisateur
     * @param port port d'ecoute de l'utilisateur
     */
    public void appelerNouvellePersonne(String ip, int port) {
        serveur.nouvelleConversation(ip, port);
    }
    /**
     * Demarre la reception du cannal udp servant au son
     */
    public void demarrerSon() {
        recepteur.start();        
    }
    /**
     * Getter conversations
     * @return la liste des conversations
     */
    public List<User> getConversations() {    return conversations;    }
    /**
     * Getter serveur
     * @return le serveur TCP
     */
    public Serveur getServeur() {   return serveur;    }
    /**
     * Getter model
     * @return le modele de donnee de l'application
     */
    public Model getModel() {   return model;    }
    /**
     * Getter emetteur
     * @return l'emetteur UDP de l'application
     */
    public EmetteurUDP getEmetteur() {   return emetteur;    }
    /**
     * Setter recepteur
     * @return recepteur UDP de l'application
     */
    public RecepteurUDP getRecepteur() {   return recepteur;    }
    /**
     * Permet de mettre en pause une conversation et d'avertir l'utilisateur
     * @param id identifiant utilisateur concerner
     * @param pause mettre en pause/reprendre une conversation
     */
    public void setPause(int id,boolean pause) {
        if(pause){
        serveur.getConversations().get(id).setStatus(EStatusConversation.PAUSE);
        serveur.sendTo(new Signalisation(EMessage.PAUSE), id);
        }else{
        serveur.getConversations().get(id).setStatus(EStatusConversation.ETABLISH);
        serveur.sendTo(new Signalisation(EMessage.REPRISE), id);   
        }
    }
    /**
     * Permet de mettre en pause une conversation
     * @param user utilisateur concerner
     * @param pause mettre en pause/reprendre une conversation
     */
    public void miseEnPause(User user,boolean pause) {
        model.miseEnPause(user, pause);
    }
    /**
     * Permet de mettre fin a une conversation
     * @param id identifiant de l'utilisateur concerner
     */
    public void racrocher(int id) {
       serveur.sendTo(new Signalisation(EMessage.FIN),id);
       serveur.getConversations().get(id).setRunning(false);
       serveur.getConversations().get(id).setStatus(EStatusConversation.FIN);
       model.deleteCallActive(id);

    }
    /**
     * Refuse une demande de conversation
     * @param id identifiant de l'utilisateur concerner
     */
    public void refuser(int id) {
       serveur.sendTo(new Signalisation(EMessage.FIN),id);
       serveur.getConversations().get(id).setRunning(false);
       serveur.getConversations().get(id).setStatus(EStatusConversation.FIN);
    }
    /**
     * Avertis la vue qu'un appel est termine ou refuse
     */
    public void avertirFinAppel(String ip, int port){
        model.avertirFinAppel(ip,port);
    }
    /**
     * Permet de couper le son d'une conversation
     * @param id identifiant de l'utilisateur concerner
     * @param mute couper/remettre le son
     */
    public void setMute(int id, boolean mute) {
        serveur.getConversations().get(id).setMute(mute);
    }
    /**
     * Ajoute un utilisateur a la liste des demandes
     * @param user utilisateur concerner
     */
    public void addCall(User user) {
        model.addCall(user);
    }
    /**
     * Ajoute un utilisateur a la liste des demandes avec le status accepter
     * @param user utilisateur concerner
     */
    public void addCallAccepter(User user) {
        model.addCall(user,EStatusCall.ACCEPT);
    }
    /**
     * Ajoute un utilisateur a la liste des conversations actives
     * @param user utilisateur concerner
     */
    public void addCallActive(User user) {
        model.addCallActive(user);
    }
    /**
     * Accepte une demande de conversation
     * @param id identifiant de l'utilisateur concerner
     */
    public void accepter(int id) {
        serveur.getConversations().get(id).setStatus(EStatusConversation.ACCEPT);
        serveur.sendTo(new Signalisation(EMessage.ACCEPT, model.getCurrentUser()),id);
    }
    /**
     * Confirme une acceptation de conversation
     * @param id identifiant de l'utilisateur concerner
     */
    public void confirmer(int id) {
        serveur.getConversations().get(id).setStatus(EStatusConversation.ETABLISH);
        serveur.sendTo(new Signalisation(EMessage.CONFIRM), id);
        if(getNbConverseActive()==1){
            demarrerSon();
            model.setUserChatActif(serveur.getConversations().get(id).getUser());
        }
    }
    /**
     * Envoie un message ecrit a l'utilisateur userChatActif
     * @param message message ecrit
     */
    public void envoyerMessage(String message, int id) {
        serveur.sendTo(new Signalisation(message), id);
        serveur.getConversations().get(id).getMessagesChat().append("Moi:");
        serveur.getConversations().get(id).getMessagesChat().append(message);
        serveur.getConversations().get(id).getMessagesChat().append("\n");
    }
    /**
     * Recupere l'historique d'une conversation
     * @return la chaine de caratere correspondant au chat
     */
    public String getHistorique(int id) {
        return serveur.getConversations().get(id).getMessagesChat().toString();
    }
    /**
     * Calcul le nombre de conversations actives
     * @return le nombre de conversations actives
     */
    public int getNbConverseActive(){
        int nb = 0;
        for(Conversation convers : serveur.getConversations()){
            if(convers.getStatus()==EStatusConversation.ETABLISH)
                nb++;
        }
        return nb;
    }
    /**
     * Force le rafraichissement de la vue
     */
    public void rafraichirvue(){
        model.notifyObserver(model);
    }
    /**
     * Setter userChatActif
     * @param userChatActif les informations de l'utilisateur destinaire du chat
     */
    public void setUserChatActif(User userChatActif){ model.setUserChatActif(userChatActif);  }
}